package Server.logic;

import java.io.IOException;
import java.sql.SQLException;
import Server.DataBase.CourseQuery;
import Server.DataBase.LessonQuery;
import Server.DataBase.ParentQuery;
import Server.DataBase.RegQuery;
import Server.DataBase.Report;
import Server.DataBase.Reports;
import Server.DataBase.RequestQuery;
import Server.DataBase.SchoolClassQuery;
import Server.DataBase.SemesterQuery;
import Server.DataBase.StudentQuery;
import Server.DataBase.TUnitQuery;
import Server.DataBase.TaskQuery;
import Server.DataBase.TeacherQuery;
import Server.DataBase.User;
import Server.DataBase.UserQuery;
import Server.Message.Message;
import Server.Message.MessageAddLesson;
import Server.Message.MessageAddSchoolClass;
import Server.Message.MessageAddSchoolClassReplay;
import Server.Message.MessageAddTask;
import Server.Message.MessageAllLesson;
import Server.Message.MessageApproveRequest;
import Server.Message.MessageAssesmentFrom;
import Server.Message.MessageAssignStudentToClass;
import Server.Message.MessageDismissRequest;
import Server.Message.MessageGetAllSchoolClassReplay;
import Server.Message.MessageGetChildren;
import Server.Message.MessageGetChildrenReplay;
import Server.Message.MessageGetClassByCourse;
import Server.Message.MessageGetCoursesReplay;
import Server.Message.MessageGetFile;
import Server.Message.MessageGetGradeTaskFile;
import Server.Message.MessageGetInfo;
import Server.Message.MessageGetLessonByCourse;
import Server.Message.MessageGetParentReplay;
import Server.Message.MessageGetRequestReplay;
import Server.Message.MessageGetStudentByClass;
import Server.Message.MessageGetStudentLesson;
import Server.Message.MessageGetStudentsInLesson;
import Server.Message.MessageGetStudentsReplay;
import Server.Message.MessageGetSubmittedFile;
import Server.Message.MessageGetSubmittedTask;
import Server.Message.MessageGetSubmittedTaskReplay;
import Server.Message.MessageGetTUnitReplay;
import Server.Message.MessageGetTask;
import Server.Message.MessageGetTaskId;
import Server.Message.MessageGetTaskIdReplay;
import Server.Message.MessageGradeTask;
import Server.Message.MessageLessonReplay;
import Server.Message.MessageLogin;
import Server.Message.MessageLoginReplay;
import Server.Message.MessageLogout;
import Server.Message.MessagePfr;
import Server.Message.MessagePfrReplay;
import Server.Message.MessagePfs;
import Server.Message.MessagePfsReplay;
import Server.Message.MessagePft;
import Server.Message.MessagePftReplay;
import Server.Message.MessageReport;
import Server.Message.MessageReport1;
import Server.Message.MessageReport2;
import Server.Message.MessageReport3;
import Server.Message.MessageSendRequest;
import Server.Message.MessageSubmitTask;
import Server.Message.MessageSubmitTaskReplay;
import Server.Message.MessageTeacherByUnit;
import Server.Message.MessageTeacherLesson;
import Server.Message.MessageTeacherReplay;
import Server.Message.MessageTeacherTUnit;
import Server.Message.MessageUnassignCourse;
import ocsf.server.ConnectionToClient;
/**
 * 
 * class handle all the massage that the client communicate with server
 *  
 *
 */
public class MsgHandeler {
	
	private Message message;
	private ConnectionToClient client;
	/**
	 * constructor MsgHandeler
	 * @param message
	 * @param client
	 */
	public MsgHandeler(Object message, ConnectionToClient client){
		this.message = (Message) message;
		this.client = client;
	}
	/**
	 * 
	 * @throws SQLException
	 * @throws IOException
	 * 
	 * msg switch cases of message type to server
	 */
	
	public void msgHandeler() throws SQLException, IOException {
		switch (message.getMessageType()){
		case MESSAGE_LOGIN:
			login();
			break;
		case MESSAGE_LOGOUT: 
			MessageLogout logout = (MessageLogout) message;
			UserQuery userQuery2 = new UserQuery();
			userQuery2.setOffline(logout.getUser().getIdUser());
			userQuery2.close();
			break;
		case MESSAGE_GET_ALL_COURSES:
			CourseQuery courseQuery = new CourseQuery();
			MessageGetCoursesReplay mgcr = new MessageGetCoursesReplay();
			mgcr.setCourseArray(courseQuery.getAllCourses());
			client.sendToClient(mgcr);
			courseQuery.close();
			break;
		case MESSAGE_GET_TUNIT:
			TUnitQuery tUnitQuery = new TUnitQuery();
			MessageGetTUnitReplay mgtr = new MessageGetTUnitReplay(tUnitQuery.getAllTUnit());
			client.sendToClient(mgtr);
			tUnitQuery.close();
			break;
		case MESSAGE_GET_ALL_CLASS:
			SchoolClassQuery classQuery = new SchoolClassQuery();
			MessageGetAllSchoolClassReplay mgacr = new MessageGetAllSchoolClassReplay(classQuery.getAllClasses());
			client.sendToClient(mgacr);
			classQuery.close();
			break;
		case MESSAGE_GET_ALL_STUDENTS:
			StudentQuery studentQuery = new StudentQuery();
			MessageGetStudentsReplay mgsr = new MessageGetStudentsReplay(studentQuery.getAllStudents());
			client.sendToClient(mgsr);
			studentQuery.close();
			break;
		case MESSAGE_GET_UNASSIGN_STUDENTS:
			StudentQuery studentQuery2 = new StudentQuery();
			MessageGetStudentsReplay mgsr2 = new MessageGetStudentsReplay(studentQuery2.getUnAssignStudents());
			client.sendToClient(mgsr2);
			studentQuery2.close();
			break;
		case MESSAGE_ADD_CLASS:
			MessageAddSchoolClass msg = (MessageAddSchoolClass) message;
			SchoolClassQuery classQuery2 = new SchoolClassQuery();
			boolean pass = false;
			if (classQuery2.addSchoolClass(msg.getClassName())==0) pass = true;
			client.sendToClient(new MessageAddSchoolClassReplay(pass));
			classQuery2.close();
			break;
		case MESSAGE_GET_STUDENT_BY_CLASS:
			MessageGetStudentByClass mgsbc = (MessageGetStudentByClass) message;
			client.sendToClient(new MessageGetStudentsReplay(new SchoolClassQuery().getStudentsInClass(mgsbc.getIdClass())));
			break;
		case MESSAGE_ASSIGN_STUDENT:
			SchoolClassQuery assign = new SchoolClassQuery();
			MessageAssignStudentToClass assignMsg = (MessageAssignStudentToClass) message;
			assign.unAssignStudents(assignMsg.getArrayRemove());
			assign.assignStudents(assignMsg.getArrayAdd(), assignMsg.getIdClass());
			break;
		case MESSAGE_NEW_SEMESTER:
			new TeacherQuery().resetHours();
			new SemesterQuery().newSemester();
			break;
		case MESSAGE_GET_CLASS_BY_COURSE:
			MessageGetClassByCourse mgcbc = (MessageGetClassByCourse) message;
			LessonQuery lq = new LessonQuery();
			client.sendToClient(new MessageGetAllSchoolClassReplay(
					lq.getClassAssignedToCourse(mgcbc.getIdCourse())));
			break;
		case MESSAGE_TEACHER_BY_UNIT:
			MessageTeacherByUnit msg1 = (MessageTeacherByUnit) message;
			client.sendToClient(new MessageTeacherReplay(
					new TeacherQuery().getTeachersByTUnit(msg1.getUnit())));
			break;
		case MESSAGE_ADD_LESSON:
			MessageAddLesson msg11 = (MessageAddLesson) message;
			client.sendToClient(new MessageGetStudentsReplay(
					new LessonQuery().addLesson(msg11.getIdCourse(), msg11.getIdClass(), msg11.getIdTeacher())));
			break;
		case MESSAGE_TEACHER_LESSON:
			MessageTeacherLesson msgtl = (MessageTeacherLesson) message;
			client.sendToClient(new MessageLessonReplay(
					new LessonQuery().getTeachersLesson(msgtl.getIdTeacher())));
			break;
		case MESSAGE_UNASSGIN_COURSES:
			MessageUnassignCourse msgun = (MessageUnassignCourse) message;
			client.sendToClient(new MessageGetCoursesReplay(
					new CourseQuery().getStudentUnassignCourses(msgun.getIdStudent())));
			break;
		case MESSAGE_LESSON_BY_COURSE:
			MessageGetLessonByCourse msglc = (MessageGetLessonByCourse) message;
			client.sendToClient(new MessageLessonReplay(
					new LessonQuery().getCoursesLesson(msglc.getIdCourse())));
			break;
		case MESSAGE_SEND_REQUEST:
			MessageSendRequest msgra = (MessageSendRequest) message;
			new RequestQuery().addRequest(msgra.getIdLesson(), msgra.getIdUser(), msgra.getMode());
			break;
		case MESSAGE_GET_STUDENT_LESSON:
			MessageGetStudentLesson msgsl = (MessageGetStudentLesson) message;
			client.sendToClient(new MessageLessonReplay(
					new LessonQuery().getStudentsLessons(msgsl.getIdStudent())));
			break;
		case MESSAGE_ADD_TASK:
			MessageAddTask msgat= (MessageAddTask) message;
			new TaskQuery().addTask(msgat.getLesson(), msgat.getDate(), msgat.getTaskFile());
			break;
		case MESSAGE_GET_TASKID:
			MessageGetTaskId msgti = (MessageGetTaskId) message;
			client.sendToClient(new MessageGetTaskIdReplay(
					new TaskQuery().getTaskId(msgti.getLesson().getIdLesson())));
			break;
		case MESSAGE_GET_INFO:
			getinfo();
			break;
		case MESSAGE_GET_TASK_FILE:
			MessageGetTask mgt = (MessageGetTask) message;
			MessageGetFile tmp = new MessageGetFile(new TaskQuery().getTaskFile(mgt.getIdLesson(), mgt.getIdTask()));
			client.sendToClient(tmp);
			break;
		case MESSAGE_GET_REQUEST:
			client.sendToClient(new MessageGetRequestReplay(
					new RequestQuery().getRequest()));
			break;
		case MESSAGE_SUBMIT_TASK:
			MessageSubmitTask mst = (MessageSubmitTask) message;
			int ontime = new TaskQuery().SubmitTask(mst.getIdTask(), mst.getIdLesson(),
					mst.getIdUser(), mst.getDate(), mst.getTaskFile());
			client.sendToClient(new MessageSubmitTaskReplay(ontime));
			break;
		case MESSAGE_APP:
			appRequest();
			break;
		case MESSAGE_DIS:
			removeRequest(((MessageDismissRequest) message).getRequest().getIdRequest());
			break;
		case MESSAGE_GET_PARENT:
			client.sendToClient(new MessageGetParentReplay(new ParentQuery().getBlockParent(),
					new ParentQuery().getUnblockParent()));
			break;
		case MESSAGE_GET_PARENT_REPLAY:
			block();
			break;
		case MESSAGE_STUDENTS_IN_LESSON:
			MessageGetStudentsInLesson mgsil = (MessageGetStudentsInLesson) message;
			client.sendToClient(new MessageGetStudentsReplay(new StudentQuery().getStudentInLesson(mgsil.getIdLesson())));
			break;
		case MESSAGE_GRADE_TASK:
			MessageGradeTask mgt2 = (MessageGradeTask) message;
			new TaskQuery().GradeTask(mgt2.getIdTask(), mgt2.getIdLesson(), 
					mgt2.getIdUser(), mgt2.getGrade(), mgt2.getCommant(), mgt2.getTaskFile());
			break;
		case MESSAGE_ASSESMENT_FORM:
			MessageAssesmentFrom maf = (MessageAssesmentFrom) message;
			new RegQuery().assesmentForm(maf.getIdUser(), maf.getIdLesson(), maf.getGrade(), maf.getComm());
			break;
		case MESSAGE_REPORT1:
			MessageReport1 mr = (MessageReport1) message;
			client.sendToClient(new Reports().getTeachersClasses(mr.getIdteacher()));
			break;
		case MESSAGE_GET_SUBMITED_TASK:
			MessageGetSubmittedTask mgst = (MessageGetSubmittedTask) message;
			client.sendToClient(new MessageGetSubmittedTaskReplay(
					new TaskQuery().getSubmittedToTask(mgst.getIdTask(), mgst.getIdLesson())));
			break;
		case MESSAGE_GET_SUBMITTED_FILE:
			MessageGetSubmittedFile mgsf = (MessageGetSubmittedFile) message;
			client.sendToClient(new MessageGetFile(
					new TaskQuery().getSubmittedFile(mgsf.getIdLesson(), mgsf.getIdTask(), mgsf.getIdUser())));
			break;
		case MESSAGE_REPORT2:
			MessageReport2 mr2 = (MessageReport2) message;
			client.sendToClient(new Reports().getClassesTeachers(mr2.getIdclass()));
			break;	
		case MESSAGE_REPORT3:
			MessageReport3 mr3 = (MessageReport3) message;
			client.sendToClient(new Reports().getClassesCourses(mr3.getIdclass()));
			break;		
		case MESSAGE_PFS:
			MessagePfs mpf = (MessagePfs) message;
			client.sendToClient(new MessagePfsReplay(
					new StudentQuery().getSemesters(mpf.getIdUser())));
			break;
		case MESSAGE_PFR:
			MessagePfr mpfr = (MessagePfr) message;
			client.sendToClient(new MessagePfrReplay(
					new RegQuery().getStudentRegInSemester(mpfr.getIduser(), mpfr.getIdsemester())));
			break;
		case MESSAGE_PFT:
			MessagePft pft = (MessagePft) message;
			client.sendToClient(new MessagePftReplay(
					new TaskQuery().getGradeTasks(pft.getIdUser(), pft.getIdLesson())));
			break;
		case MESSAGE_GET_CHILDREN:
			MessageGetChildren mgc = (MessageGetChildren) message;
			client.sendToClient(new MessageGetChildrenReplay(
					new ParentQuery().getChildren(mgc.getIdUser())));
			break;
		case MESSAGE_GET_GRADE_FILE:
			MessageGetGradeTaskFile tf = (MessageGetGradeTaskFile) message;
			client.sendToClient(new MessageGetFile(
					new TaskQuery().getGradeFile(tf.getIdLesson(), tf.getIdTask(), tf.getIdUser())));
			break;
		case MESSAGE_TEACHER_TUNIT:
			MessageTeacherTUnit mtu = (MessageTeacherTUnit) message;
			client.sendToClient(new MessageGetTUnitReplay(
					new TUnitQuery().getTeacherTunit(mtu.getIdTeacher())));
			break;
		case MESSAGE_ALL_LESSONS:
			MessageAllLesson mal = (MessageAllLesson) message;
			client.sendToClient(new MessageLessonReplay(
					new LessonQuery().getAllCoursesLesson(mal.getIdCourse())));
			break;
		case MESSAGE_REPORT:
			report();
			break;
		}
	}
	/**
	 * user are login to systerm verify password and user name
	 * and client set connected to server
	 * @throws SQLException
	 * @throws IOException
	 */
	private void login() throws SQLException, IOException{
		String str=null;
		boolean pass =true;
		User user = null;
		MessageLogin login = (MessageLogin) message;
		
		UserQuery userQuery = new UserQuery();
		if (userQuery.isExist(login.getUserName())){
			user = userQuery.getUserByName(login.getUserName());
			if (login.getPassword().equals(user.getPassword())){
				if (user.isOnline()==1){
					pass = false;
					str = "User already login, try again later.";
				}
				else {
					if (user.getPermission()==4 && new ParentQuery().isBlock(user.getIdUser())){
						pass = false;
						str = "You have been blocked by the manager, for more information please contact Baglama DevTeam.";
					}
				}
			}
			else {
				str = "Forgot your password? please contact Baglama DevTeam.";
				pass=false;
			}
		}
		else {
				if (login.getUserName().isEmpty())
					str = "Please enter user name.";
				else
					str = "Wrong user name, please try again.";
				pass= false;
			}
		if (pass) userQuery.setOnline(user.getIdUser());
		userQuery.close();
		client.sendToClient(new MessageLoginReplay(pass, user, str));
	}
	/**
	 * 
	 * @throws SQLException parents is blocke
	 */
	private void block() throws SQLException{
		MessageGetParentReplay msg = (MessageGetParentReplay) message;
		ParentQuery pq = new ParentQuery();
		pq.block(msg.getBlock());
		pq.unblock(msg.getUnblock());
	}
	/**
	 * 
	 * @throws SQLException
	 */
	private void appRequest() throws SQLException{
		MessageApproveRequest msg = (MessageApproveRequest) message;
		switch(msg.getRequest().getMode())
		{
			case 1:
				new RegQuery().regStudentToLessonByRequest(msg.getRequest().getUser(), msg.getRequest().getLesson().getIdLesson());
				break;
			case 2:
				new RegQuery().removeReg(msg.getRequest());
				break;
			case 3:
				new LessonQuery().changeTeacher(msg.getRequest());
				break;
		}
		removeRequest(msg.getRequest().getIdRequest());
	}
	/**
	 * 
	 * @param idRequest
	 * @throws SQLException
	 */
	private void removeRequest(int idRequest) throws SQLException{
		new RequestQuery().removeRequest(idRequest);
	}
	
	private void getinfo() throws IOException, SQLException{
		switch (((MessageGetInfo)message).getTable()){
		case STUDENT:
			client.sendToClient(new MessageGetStudentsReplay(
					new StudentQuery().getTable()));
			break;
		case TEACHER:
			client.sendToClient(new MessageTeacherReplay(
					new TeacherQuery().getTeachersByTUnit(0)));
			break;
		case COURSE:
			client.sendToClient(new MessageGetCoursesReplay(
					new CourseQuery().getAllCourses()));
			break;
		case CLASS:
			client.sendToClient(new MessageGetAllSchoolClassReplay(
					new SchoolClassQuery().getAllClasses()));
			break;
		}
	}
	
	private void report() throws SQLException, IOException{
		MessageReport msg = (MessageReport) message;
		switch (msg.getType()){
		case 1:
			client.sendToClient(new MessageReport(new Reports().getReportsIF(), 2));
			break;
		case 2:
			Report r = new Reports().getReport(msg.getId());
			MessageReport rep =new MessageReport();
			switch (r.getInfo()){
			case 1: // all Teachers
				rep.setArray(new TeacherQuery().getTeachers());
				break;
			case 2:
				rep.setArray(new SchoolClassQuery().getClasses());
				break;
			}
			client.sendToClient(rep);
			break;
		case 3:
			client.sendToClient(new Reports().getQuery(msg.getIdRep(), msg.getId()));
			break;
		}
	}
}
